package com.ourchem.web.controller.monitor;

import java.util.*;
import java.util.stream.Collectors;

import com.ourchem.common.utils.DateUtils;
import com.ourchem.system.dto.PvDTO;
import com.ourchem.system.dto.UvDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.ourchem.common.annotation.Log;
import com.ourchem.common.core.controller.BaseController;
import com.ourchem.common.core.domain.AjaxResult;
import com.ourchem.common.core.page.TableDataInfo;
import com.ourchem.common.enums.BusinessType;
import com.ourchem.common.utils.poi.ExcelUtil;
import com.ourchem.system.domain.SysOperLog;
import com.ourchem.system.service.ISysOperLogService;

/**
 * 操作日志记录
 * 
 * @author ourchem
 */
@RestController
@RequestMapping("/monitor/operlog")
public class SysOperlogController extends BaseController
{
    @Autowired
    private ISysOperLogService operLogService;

    @PreAuthorize("@ss.hasPermi('monitor:operlog:list')")
    @GetMapping("/list")
    public TableDataInfo list(SysOperLog operLog)
    {
        startPage();
        List<SysOperLog> list = operLogService.selectOperLogList(operLog);
        return getDataTable(list);
    }

    @PreAuthorize("@ss.hasPermi('monitor:operlog:list')")
    @GetMapping("/detail_list")
    public TableDataInfo detailList(SysOperLog operLog,
             @RequestParam(name = "statType",required = true) Integer statType,
             @RequestParam(name = "type",required = true) Integer type,
             @RequestParam(name = "startTime",required = true) String startTime
            ,@RequestParam(name = "endTime",required = true)String endTime)
    {
        startPage();
        List<SysOperLog> list = selectOperLogDetailList(operLog, statType, type, startTime, endTime);
        return getDataTable(list);
    }

    @Log(title = "操作日志", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('monitor:operlog:export')")
    @GetMapping("/export")
    public AjaxResult export(SysOperLog operLog,
             @RequestParam(name = "statType",required = true) Integer statType,
             @RequestParam(name = "type",required = true) Integer type,
             @RequestParam(name = "startTime",required = true) String startTime
            ,@RequestParam(name = "endTime",required = true)String endTime)
    {
        List<SysOperLog> list = selectOperLogDetailList(operLog, statType, type, startTime, endTime);
        ExcelUtil<SysOperLog> util = new ExcelUtil<SysOperLog>(SysOperLog.class);
        return util.exportExcel(list, "操作日志");
    }

    private List<SysOperLog> selectOperLogDetailList(SysOperLog operLog, Integer statType, Integer type, String startTime, String endTime){
        Date startDate = DateUtils.parseDate(startTime);
        Date endDate = DateUtils.parseDate(endTime);
        endDate = getLastDay(endDate, type);
        Map<String, Object> map = new HashMap<>();
        if(startTime != null) {
            map.put("beginTime", DateUtils.parseDateToStr("yyyyMMdd", startDate));
        }
        if(endTime != null) {
            map.put("endTime", DateUtils.parseDateToStr("yyyyMMdd", endDate));
        }
        map.put("type", type);
        operLog.setParams(map);
        operLog.setBusinessType(10);
        List<SysOperLog> list = null;
        if(statType == 0) {
            list = operLogService.selectOperLogDetailList(operLog);
        }else{
            list = operLogService.selectOperLogUvDetailList(operLog);
        }
        return list;
    }

    @Log(title = "操作日志", businessType = BusinessType.DELETE)
    @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
    @DeleteMapping("/{operIds}")
    public AjaxResult remove(@PathVariable Long[] operIds)
    {
        return toAjax(operLogService.deleteOperLogByIds(operIds));
    }

    @Log(title = "操作日志", businessType = BusinessType.CLEAN)
    @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
    @DeleteMapping("/clean")
    public AjaxResult clean()
    {
        operLogService.cleanOperLog();
        return AjaxResult.success();
    }

    /**
     * PV访问量
     * @return
     */
    @Log(title = "PV访问量", businessType = BusinessType.CLEAN)
    @PreAuthorize("@ss.hasPermi('monitor:operlog:list')")
    @GetMapping("/pvCount")
    public AjaxResult pvCount(@RequestParam(name = "type",required = true) Integer type, @RequestParam(name = "startTime",required = true) String startTime
            , @RequestParam(name = "endTime",required = true) String endTime) {
        Date startDate = DateUtils.parseDate(startTime);
        Date endDate = DateUtils.parseDate(endTime);
        endDate = getLastDay(endDate, type);

        List<PvDTO> list = operLogService.pvCount(startDate, endDate, type);
        return AjaxResult.success(list);
    }

    /**
     * UV访问量
     * @return
     */
    @Log(title = "UV访问量", businessType = BusinessType.CLEAN)
    @PreAuthorize("@ss.hasPermi('monitor:operlog:list')")
    @GetMapping("/uvCount")
    public AjaxResult uvCount(@RequestParam(name = "type",required = true) Integer type, @RequestParam(name = "startTime",required = true) String startTime
            , @RequestParam(name = "endTime",required = true) String endTime) {
        Date startDate = DateUtils.parseDate(startTime);
        Date endDate = DateUtils.parseDate(endTime);
        endDate = getLastDay(endDate, type);

        SysOperLog params = new SysOperLog();

        List<SysOperLog> detailList = selectOperLogDetailList(params, 1, type, startTime, endTime);
        List<UvDTO> list = new ArrayList<>();
        if(detailList != null && detailList.size() > 0){
            Map<String, Long> map = detailList.stream().collect(Collectors.groupingBy(SysOperLog::getVisitDate, Collectors.counting()));
            Set<String> keys = map.keySet();

            for (String s : keys) {
                UvDTO uv = new UvDTO();
                uv.setDate(s);
                uv.setCount(map.get(s));
                list.add(uv);
            }
        }
        return AjaxResult.success(list);
//        List<UvDTO> list = operLogService.uvCount(startDate, endDate, type);
//        return AjaxResult.success(list);
    }

    private Date getLastDay(Date date, Integer type){
        if(type == 1){
            date = org.apache.commons.lang3.time.DateUtils.addMonths(date, 1);
        }else{
            date = org.apache.commons.lang3.time.DateUtils.addDays(date, 1);
        }
        date = org.apache.commons.lang3.time.DateUtils.addSeconds(date, -1);
        return date;
    }

}
